package com.baturu.vin.benz.service.impl.supers;

import com.baturu.vin.benz.consts.BenzConstant;
import com.baturu.vin.benz.dal.dao.BenzModelDAO;
import com.baturu.vin.benz.dal.dao.BenzSpringDAO;
import com.baturu.vin.benz.dal.dao.BenzVinCarTypeInfoDAO;
import com.baturu.vin.benz.dto.*;
import com.baturu.vin.benz.service.impl.BenzCarTypeInfoService;
import com.baturu.vin.benz.service.impl.BenzEPCPartsService;
import com.baturu.vin.benz.service.impl.util.BenzI18nService;
import com.baturu.vin.benz.service.impl.util.BenzStringUtil;
import com.baturu.vin.benz.utils.BenzValidator;
import com.baturu.vin.kit.VinValidator;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * BenzSuperCarTypeService
 * 奔驰超级epc vin/车型信息
 *
 * @author majianming
 * @date 2019-04-03 15:30
 */
@Service
public class BenzSuperCarTypeService implements InitializingBean {


    /**
     * 地区与查询的表
     */
    private static Map<String, String> DB_NAME_BY_LOCATION = Maps.newHashMap();


    @Autowired
    private BenzVinCarTypeInfoDAO benzVinCarTypeInfoDAO;

    @Autowired
    private BenzCarTypeInfoService benzCarTypeInfoService;

    @Autowired
    private BenzEPCPartsService benzEPCPartsService;

    @Autowired
    private BenzSpringDAO benzSpringDAO;

    @Autowired
    private BenzModelDAO benzModelDAO;

    @Autowired
    private BenzI18nService benzI18nService;


    /**
     * 预先缓存的表信息
     *
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        DB_NAME_BY_LOCATION = benzVinCarTypeInfoDAO.findDbNameByLocation().stream()
                .collect(Collectors.toMap(k -> k.get("location"), k -> k.get("dbName"), (k1, k2) -> k1));
    }

    /**
     * 通过fin查询vin信息
     *
     * @param fin vin后8位
     * @return 查询到的vin信息
     */
    List<BenzVinFinInfoDTO> queryVinInfoByFin(String fin) {
        if (BenzValidator.invalidFin(fin)) {
            return Collections.emptyList();
        }
        return benzVinCarTypeInfoDAO.finVinInfosByFin(fin);
    }


    /**
     * 查询db 的名称
     *
     * @param location
     * @return
     */
    public String queryDbNameByLocation(String location) {
        if (StringUtils.isBlank(location) || BenzConstant.NO_DEAL_LOCATION.contains(location)) {
            return null;
        }
        return DB_NAME_BY_LOCATION.get(location);
    }

    /**
     * 通过vin和db信息查询sa
     *
     * @return saCode为键，sa信息集合为值
     */
    private Set<BenzSaDescDTO> querySaCodeByVinAndDbName(BenzVinFinInfoDTO benzVinFinInfoDTO, String productDate) {
        Set<String> saCodes = benzVinCarTypeInfoDAO.findSACodeByDbName(benzVinFinInfoDTO.getWhc(),
                benzVinFinInfoDTO.getChassbm(),
                benzVinFinInfoDTO.getChassIdent(),
                benzVinFinInfoDTO.getDbName());
//        转换sa信息
        Set<String> saCodeSet = BenzStringUtil.getSaCodeSet(saCodes);

        if (CollectionUtils.isEmpty(saCodeSet)) {
            return Collections.emptySet();
        }
        String chassbm = Strings.padEnd(benzVinFinInfoDTO.getChassbm(), 6, ' ');
        String modelPrefix3 = chassbm.substring(0, 3);
        Set<String> typesSet = Sets.newHashSet(modelPrefix3, modelPrefix3 + "." + chassbm.substring(3, 4), modelPrefix3 + "." + chassbm.substring(3, 5), modelPrefix3 + "." + chassbm.substring(3, 6));
//         查询sa 码信息
        List<BenzSaDescDTO> saDesc = benzVinCarTypeInfoDAO.findSaDesc(productDate, typesSet, saCodeSet, benzI18nService.getBenzLangEnum().getLandCode());
        Set<String> saDescCodes = saDesc.stream().map(BenzSaDescDTO::getSaCode).collect(Collectors.toSet());
        Collection<String> retainSaSet = Sets.difference(saCodeSet, saDescCodes);
        saDesc.addAll(retainSaSet.stream().map(s -> BenzSaDescDTO.builder().saCode(s).saDesc(benzI18nService.trans("no_sacode_description")).build()).collect(Collectors.toList()));
        return new HashSet<>(saDesc);
    }

    private BenzSuperCarConfigurationDTO queryCarConfigurationByVinAndDbName(BenzVinFinInfoDTO benzVinFinInfoDTO) {
        BenzVinInfoDTO benzVinInfoDTO = benzVinCarTypeInfoDAO.finCarTypeByDBName(
                benzVinFinInfoDTO.getWhc(),
                benzVinFinInfoDTO.getChassbm(),
                benzVinFinInfoDTO.getChassIdent(),
                benzVinFinInfoDTO.getDbName());

        if (Objects.isNull(benzVinInfoDTO) || !benzEPCPartsService.rebuildVinCarTypeInfo(benzVinInfoDTO)) {
            return null;
        }
        //        查询sa 信息
        Set<BenzSaDescDTO> benzSaDescDTOS = querySaCodeByVinAndDbName(benzVinFinInfoDTO, benzVinInfoDTO.getAdate());

        Set<String> saCodeSet = benzSaDescDTOS.stream().map(BenzSaDescDTO::getSaCode).collect(Collectors.toSet());

        //排量,变速箱类型,档位
        benzEPCPartsService.dealDisplacementAndTransInfo(saCodeSet, benzVinInfoDTO);

        benzVinInfoDTO.setSaCodeSet(saCodeSet);


        // 根据vin的底盘号等信息 获取 catNum,
        String appInf = BenzStringUtil.buildAppInf(benzVinFinInfoDTO.getLocation());
        Map<String, BenzPartCatInfoDTO> catInfoMap = getCatInfoMap(benzVinInfoDTO, appInf);

        /*
       如果两步都找不到btrid 那就不管了 这个btrid 用来带出车型图片的
        */
        String btrId = benzVinCarTypeInfoDAO.findBtrId(benzVinInfoDTO);
        //找到车型
        if (StringUtils.isBlank(btrId)) {
            btrId = benzVinCarTypeInfoDAO.findBtrIdWithoutDisAndTrans(benzVinInfoDTO);
        }
//        车身信息
//        如果没有车身信息 那么直接表示这个解析不了
        BenzPartCatInfoDTO chassInfo = catInfoMap.get(BenzConstant.CHASS_INFO_KEY);
        if (Objects.isNull(chassInfo) || !BenzConstant.HAS_ANALYSIS_CAR_CLASS_NO_SET.contains(chassInfo.getClassNo())) {
            return null;
        }
//        变速箱信息
        String transmissionName = "";
        BenzPartCatInfoDTO transmissionInfo = catInfoMap.get(BenzConstant.TRANSMISSION_INFO_KEY);
        String transmissionInfoCatalog = "";
        if (Objects.nonNull(transmissionInfo)) {
            transmissionInfoCatalog = transmissionInfo.getCatalog();
            transmissionName = transmissionInfo.getType() + transmissionInfo.getSubbm1() + " " + transmissionInfo.getSalesDes();
        }
//        发动机信息
        String engineName = "";
        String engineInfoCatalog = "";
        BenzPartCatInfoDTO engineInfo = catInfoMap.get(BenzConstant.ENGINE_INFO_KEY);
        if (Objects.nonNull(engineInfo)) {
            engineInfoCatalog = engineInfo.getCatalog();
            engineName = engineInfo.getType() + engineInfo.getSubbm1() + " " + engineInfo.getSalesDes();
        }
//        查询机组信息
        String masterDesc = StringUtils.trim(benzVinCarTypeInfoDAO.findMasterDescWithDBName(benzVinFinInfoDTO.getWhc(),
                benzVinFinInfoDTO.getChassbm(),
                benzVinFinInfoDTO.getChassIdent(),
                benzVinFinInfoDTO.getDbName()));

        String etvbm = "";
        String zuText = "";
        String masterDescTrans = masterDescTrans(masterDesc);
        if (StringUtils.isNotBlank(masterDescTrans)) {
            etvbm = benzVinCarTypeInfoDAO.findEtvbm(masterDescTrans, engineInfo.getType() + engineInfo.getSubbm1());
            zuText = benzVinCarTypeInfoDAO.findZuText(masterDescTrans);
        }


//       查询车型信息
        List<BenzModelDTO> benzModelDTOS = benzModelDAO.queryCarModelInfo(chassInfo.getCatalog(), chassInfo.getType() + "." + chassInfo.getSubbm1(), benzI18nService.getBenzLangEnum().getLandCode());


//        先使用 DC_MODEL_DESC_V 的 MDLDESC 如果没有 那么使用车型的销售名称
        String saleName = benzModelDAO.queryCarModelDesc(benzVinFinInfoDTO.getWhc(), benzVinFinInfoDTO.getChassbm(), benzVinInfoDTO.getModelIndex());
        if (StringUtils.isBlank(saleName)) {
            saleName = chassInfo.getSalesDes();
        }

        return BenzSuperCarConfigurationDTO
                .builder()
                .btrId(btrId)
                .engine(benzVinInfoDTO.getEngine())
                .engineName(engineName)
                .brandName(StringUtils.equals(chassInfo.getClassNo(), "F") ? "SMART" : "奔驰")
                .salesModel(saleName)

                .type(chassInfo.getType())
                .subModel1(chassInfo.getSubbm1())

                .model(chassInfo.getType() + "." + chassInfo.getSubbm1())
                .modelInfos(benzModelDTOS)
                .motorSachNummer(masterDesc)
                .shortEngine(benzVinInfoDTO.getShortEngine())

                .transmission(benzVinInfoDTO.getTransmission())
                .shortTransmission(benzVinInfoDTO.getShortTransmission())
                .transmissionName(transmissionName)

                .deliveryDate(benzVinInfoDTO.getDeliveryDate())
                .releaseDate(benzVinInfoDTO.getReleaseDate())

                .interior(benzVinInfoDTO.getInterior())

                .paint1(benzVinInfoDTO.getPaint1())
                .paint2(benzVinInfoDTO.getPaint2())
                .paint3(benzVinInfoDTO.getPaint3())
                .paint4(benzVinInfoDTO.getPaint4())
                .paint5(benzVinInfoDTO.getPaint5())

                .steering(benzVinInfoDTO.getSteering())

                .frontAxle1(benzVinInfoDTO.getFrontAxle1())
                .rearAxle1(benzVinInfoDTO.getRearAxle1())

                .transferCase(benzVinInfoDTO.getTransferCase())

                .productDate(benzVinInfoDTO.getAdate())
                .productYear(benzVinInfoDTO.getDateyear())

                .country(benzVinInfoDTO.getCountry())


                .interiorDes(benzVinInfoDTO.getInteriorDes())
                .paintDes(benzVinInfoDTO.getPaintDes())

                .orderNumber(benzVinInfoDTO.getOrderNum())
                .benzVinInfoDTO(benzVinInfoDTO)

                .catInfoMap(catInfoMap)
                .carNo(chassInfo.getCatalog())
                .engineNo(engineInfoCatalog)
                .transmissionNo(transmissionInfoCatalog)
                .benzSaDescDTOS(benzSaDescDTOS)
                .etvBM(etvbm)
                .zuText(zuText)
                .build();

    }

    /**
     * 转换机组信息
     *
     * @param masterDesc
     * @return
     */
    private String masterDescTrans(String masterDesc) {
        if (StringUtils.length(masterDesc) < 11) {
            return "";
        }
        return "A" + masterDesc.substring(4, 7) + masterDesc.substring(9, 11) + masterDesc.substring(1, 4) + "  " + masterDesc.substring(7, 9);
    }

    /**
     * 车型配置信息
     *
     * @param benzVinInfoDTO
     * @param appInf
     * @return
     */
    private Map<String, BenzPartCatInfoDTO> getCatInfoMap(BenzVinInfoDTO benzVinInfoDTO, String appInf) {
        String chassBm = benzVinInfoDTO.getChassbm();

        String engineNum = StringUtils.isNotBlank(benzVinInfoDTO.getEngine()) && benzVinInfoDTO.getEngine().length() >= 6 ? benzVinInfoDTO.getEngine().substring(0, 6) : "";
        benzVinInfoDTO.setShortEngine(engineNum);

        String transmissionNum = StringUtils.isNotBlank(benzVinInfoDTO.getTransmission()) && benzVinInfoDTO.getTransmission().length() >= 6 ? benzVinInfoDTO.getTransmission().substring(0, 6) : "";
        benzVinInfoDTO.setShortTransmission(transmissionNum);

        List<BenzPartCatInfoDTO> allCatInfos = benzCarTypeInfoService.getCatInfos(Sets.newHashSet(chassBm, engineNum, transmissionNum), appInf);
        String classNo = BenzStringUtil.getCatClassNo(allCatInfos);
        Map<String, List<BenzPartCatInfoDTO>> collect = allCatInfos.stream().collect(Collectors.groupingBy(b -> b.getType() + b.getSubbm1()));
        List<BenzPartCatInfoDTO> chassCatInfos = collect.get(chassBm);
        List<BenzPartCatInfoDTO> engineCatInfos = collect.get(engineNum);
        List<BenzPartCatInfoDTO> transCatInfos = collect.get(transmissionNum);

        Map<String, BenzPartCatInfoDTO> catInfoMap = Maps.newHashMap();
        if (StringUtils.isNotBlank(chassBm) && CollectionUtils.isNotEmpty(chassCatInfos)) {
            BenzPartCatInfoDTO benzPartCatInfoDTO = benzCarTypeInfoService.filterByClassNo(chassCatInfos, classNo);
            if (Objects.nonNull(benzPartCatInfoDTO)) {
                catInfoMap.put(BenzConstant.CHASS_INFO_KEY, benzPartCatInfoDTO);
            }
        }
        if (StringUtils.isNotBlank(engineNum) && CollectionUtils.isNotEmpty(engineCatInfos)) {
            BenzPartCatInfoDTO benzPartCatInfoDTO = benzCarTypeInfoService.filterByClassNo(engineCatInfos, classNo);
            if (Objects.nonNull(benzPartCatInfoDTO)) {
                catInfoMap.put(BenzConstant.ENGINE_INFO_KEY, benzPartCatInfoDTO);
            }
        }
        if (StringUtils.isNotBlank(transmissionNum) && CollectionUtils.isNotEmpty(transCatInfos)) {
            BenzPartCatInfoDTO benzPartCatInfoDTO = benzCarTypeInfoService.filterByClassNo(transCatInfos, classNo);
            if (Objects.nonNull(benzPartCatInfoDTO)) {
                catInfoMap.put(BenzConstant.TRANSMISSION_INFO_KEY, benzPartCatInfoDTO);
            }
        }
        return catInfoMap;
    }

    /**
     * 查询车型信息
     *
     * @param vin 需要查询的17位vin 信息
     * @return 车型配置
     */
    BenzSuperCarInfoDTO queryCarVinInfo(String vin) {
        if (!VinValidator.simpleValidate(vin)) {
            return null;
        }
        String vin14 = vin.substring(3, 17);
        List<BenzVinFinInfoDTO> benzVinFinInfoDTOS = benzVinCarTypeInfoDAO.finFinByVin14OrWhc(vin14, vin.substring(0, 3), vin.substring(3, 9), vin.substring(9, 17));
        benzVinFinInfoDTOS.removeIf(l -> BenzConstant.NO_DEAL_LOCATION.contains(l.getLocation()));
        if (CollectionUtils.isEmpty(benzVinFinInfoDTOS)) {
            return null;
        }
        BenzVinFinInfoDTO benzVinFinInfoDTO;
        if (benzVinFinInfoDTOS.size() == 1) {
            benzVinFinInfoDTO = benzVinFinInfoDTOS.get(0);
        } else {
            Optional<BenzVinFinInfoDTO> any = benzVinFinInfoDTOS.stream().filter(b -> b.getVin().equals(vin14)).findAny();
            benzVinFinInfoDTO = any.orElseGet(() -> benzVinFinInfoDTOS.get(0));
        }

        if (benzVinFinInfoDTO == null || StringUtils.isBlank(benzVinFinInfoDTO.getLocation())) {
            return null;
        }
        String location = queryDbNameByLocation(benzVinFinInfoDTO.getLocation());
        if (StringUtils.isBlank(location)) {
            return null;
        }
        benzVinFinInfoDTO.setDbName(location);


//        查询车型配置信息
        BenzSuperCarConfigurationDTO benzSuperCarConfigurationDTO = queryCarConfigurationByVinAndDbName(benzVinFinInfoDTO);
        if (Objects.isNull(benzSuperCarConfigurationDTO)) {
            return null;
        }


//        查询弹簧信息
        BenzSpringsDTO benzSpringsDTO = queryBenzSpringInfo(benzVinFinInfoDTO);


        return BenzSuperCarInfoDTO.builder()
                .vinCode(vin)
                .whc(benzVinFinInfoDTO.getWhc())
                .chassbm(benzVinFinInfoDTO.getChassbm())
                .chassIdent(benzVinFinInfoDTO.getChassIdent())
                .dbName(benzVinFinInfoDTO.getDbName())
                .benzSpringsDTO(benzSpringsDTO)
                .benzSuperCarConfigurationDTO(benzSuperCarConfigurationDTO)
                .build();
    }

    /**
     * 获取弹簧信息
     *
     * @param benzVinFinInfoDTO
     * @return
     */
    private BenzSpringsDTO queryBenzSpringInfo(BenzVinFinInfoDTO benzVinFinInfoDTO) {
        BenzSpring benzSpring = benzSpringDAO.getBenzSpring(benzVinFinInfoDTO.getWhc(), benzVinFinInfoDTO.getChassbm(), benzVinFinInfoDTO.getChassIdent());
        if (Objects.isNull(benzSpring)) {
            return null;
        }
//        下面这里开始国际化
        return BenzSpringsDTO.builder()
                .frontSpringStrut(
                        BenzSpringsDTO.SpringDesc.builder()
                                .key("frontSpringStrut")
                                .desc("前悬架滑柱")
                                .value(benzSpring.getFrontSpringStrut())
                                .build()
                )
                .frontSpring(
                        BenzSpringsDTO.SpringDesc.builder()
                                .key("frontSpring")
                                .desc("前部弹簧")
                                .value(benzSpring.getFrontSpring())
                                .build()
                )
                .rearSpring(
                        BenzSpringsDTO.SpringDesc.builder()
                                .key("rearSpring")
                                .desc("后部弹簧")
                                .value(benzSpring.getRearSpring())
                                .build()
                )
                .rearSpringSuppl(
                        BenzSpringsDTO.SpringDesc.builder()
                                .key("rearSpringSuppl")
                                .desc("后部垫片")
                                .value(benzSpring.getRearSpringSuppl())
                                .build()
                )
                .build();
    }
}
